#include <iostream>
#include <cstring>
#include <time.h>
#include "tinyxml/tinyxml.h"
#include "tinyxml/tinystr.h"
#include "config.h"

using namespace std;

CONF conf;

int init(const char *conf_file)
{
	memset(&conf, 0, sizeof conf);
	TiXmlDocument conf_doc(conf_file);
	if (!conf_doc.LoadFile())
		return -1;
	TiXmlElement *root_element = conf_doc.RootElement();
	if (root_element == NULL)
		return -1;
	TiXmlElement *servers = root_element->FirstChildElement("servers");
	TiXmlElement *manage = root_element->FirstChildElement("manage");
	TiXmlElement *client = root_element->FirstChildElement("client");
	if (servers == NULL || manage == NULL || client == NULL)
		return -1;





	TiXmlElement *url_dist = servers->FirstChildElement("url_dist");
	TiXmlElement *page_collect = servers->FirstChildElement("page_collect");
	if (url_dist == NULL || page_collect == NULL)
		return -1;




	/*
	 * 读取关于URL分发服务的配置
	 **/
	TiXmlElement *server = url_dist->FirstChildElement("server");
	if (server == NULL)
		return -1;
	TiXmlNode *ip = server->FirstChild("ip");
	TiXmlNode *port = server->FirstChild("port");
	if (ip == NULL || port == NULL)
		return -1;
	while (ip != NULL && port != NULL) {
		conf.url_server = (struct addr *)realloc(conf.url_server, sizeof(struct addr) * (conf.url_server_num + 1));
		if (conf.url_server == NULL)
			return -1;
		if (!ip->FirstChild())
			return -1;
		const char *p = ip->FirstChild()->Value();
		if (!inet_aton(p, &conf.url_server[conf.url_server_num].ip)) {
			free(conf.url_server);
			return -1;
		}
		if (!port->FirstChild())
			return -1;
		conf.url_server[conf.url_server_num].port = atoi(port->FirstChild()->Value());
		conf.url_server_num++;
		server = server->NextSiblingElement("server");
		if (server == NULL)
			break;
		ip = server->FirstChild("ip");
		port = server->FirstChild("port");
	}




	/*
	 * 读取关于网页上报服务的配置
	 * */
	server = page_collect->FirstChildElement("server");
	if (server == NULL) {
		free(conf.url_server);
		return -1;
	}
	ip = server->FirstChild("ip");
	port = server->FirstChild("port");
	if (ip == NULL || port == NULL) {
		free(conf.url_server);
		return -1;
	}
	while (ip != NULL && port != NULL) {
		conf.page_server = (struct addr *)realloc(conf.page_server, sizeof(struct addr) * (conf.page_server_num + 1));
		if (conf.page_server == NULL) {
			free(conf.url_server);
			return -1;
		}
		if (!ip->FirstChild())
			return -1;
		const char *p = ip->FirstChild()->Value();
		if (!inet_aton(p, &conf.page_server[conf.page_server_num].ip)) {
			free(conf.url_server);
			free(conf.page_server);
			return -1;
		}
		if (!port->FirstChild())
			return -1;
		conf.page_server[conf.page_server_num].port = atoi(port->FirstChild()->Value());
		conf.page_server_num++;
		server = server->NextSiblingElement("server");
		if (server == NULL)
			break;
		ip = server->FirstChild("ip");
		port = server->FirstChild("port");
	}



	/*
	 * 读取管理端口配置
	 **/
	ip = manage->FirstChild("bind_ip");
	port = manage->FirstChild("bind_port");
	if (ip == NULL || port == NULL) {
		free(conf.url_server);
		free(conf.page_server);
		return -1;
	}
	if (!ip->FirstChild())
		return -1;
	if (!inet_aton(ip->FirstChild()->Value(), &conf.manage.ip)) {
		free(conf.url_server);
		free(conf.page_server);
		return -1;
	}
	if (!port->FirstChild())
		return -1;
	conf.manage.port = atoi(port->FirstChild()->Value());
	



	/*
	 * 读取关于作为http客户端的配置
	 **/
	TiXmlNode *node = client->FirstChild("threads_num");
	if (node == NULL) 
		conf.threads_num = DEFAULT_THREADS_NUM;
	else if (!node->FirstChild())
		return -1;
	else	
		conf.threads_num = atoi(node->FirstChild()->Value());
	node = client->FirstChild("per_thread_conn");
	if (node == NULL)
		conf.per_thread_conn = DEFAULT_PER_THREAD_CONN;
	else if (!node->FirstChild())
		return -1;
	else	
		conf.per_thread_conn = atoi(node->FirstChild()->Value());
	node = client->FirstChild("per_thread_uris");
	if (node == NULL)
		conf.per_thread_uris = DEFAULT_PER_THREAD_URLS;
	else if (!node->FirstChild())
		return -1;
	else	
		conf.per_thread_uris = atoi(node->FirstChild()->Value());
	node = client->FirstChild("per_site_conn");
	if (node == NULL)
		conf.per_site_conn = DEFAULT_PER_SITE_CONN;
	else if (!node->FirstChild())
		return -1;
	else
		conf.per_site_conn = atoi(node->FirstChild()->Value());
	node = client->FirstChild("page_save_template");
	if (node == NULL)
		strcpy(conf.file_temp, "");
	else if (!node->FirstChild())
		return -1;
	else {
		strncpy(conf.file_temp, node->FirstChild()->Value(), sizeof(conf.file_temp) - 1);
		conf.file_temp[sizeof(conf.file_temp) - 1] = '\0';
	}

	TiXmlElement *http_request = client->FirstChildElement("http_request");
	node = http_request->FirstChild("method");
	if (node == NULL)
		strcpy(conf.req_header.method, DEFAULT_METHOD);
	else if (!node->FirstChild())
		return -1;
	else
		strncpy(conf.req_header.method, node->FirstChild()->Value(), sizeof(conf.req_header.method) - 1);
	node = http_request->FirstChild("http_version");
	if (node == NULL)
		strcpy(conf.req_header.http_ver, DEFAULT_HTTP_VER);
	else if (!node->FirstChild())
		return -1;
	else
		strncpy(conf.req_header.http_ver, node->FirstChild()->Value(), sizeof(conf.req_header.http_ver) - 1);

	/*
	 * 加载http请求头属性配置
	 **/
	const char *attr_name, *attr_value;
	TiXmlElement *attr = client->FirstChildElement("attr");
	while (attr) {
		attr_name = attr->Attribute("attr_name");
		attr_value = attr->Attribute("attr_value");
		if (!attr_name || !attr_value)
			continue;
		conf.req_header.attr = (struct http_attr *)realloc(conf.req_header.attr, 
				sizeof(struct http_attr) * (conf.req_header.attr_num + 1));
		conf.req_header.attr[conf.req_header.attr_num].attr_name = strdup(attr_name);
		conf.req_header.attr[conf.req_header.attr_num].attr_value = strdup(attr_value);
		conf.req_header.attr_num++;
		attr = attr->NextSiblingElement("attr");
	}

	conf.init_time = time(NULL);

	return 0;
}
